package com.nt.thah.configuration;

import com.alibaba.fastjson.JSON;
import com.google.common.base.Strings;
import com.nt.thah.constant.SysCode;
import com.nt.thah.enums.ResultCode;
import com.nt.thah.utils.DateUtil;
import com.nt.thah.utils.JwtTokenUtil;
import com.nt.thah.web.ApiResult;
import com.nt.thah.web.UserContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;

/**
 * @Description: 认证拦截器
 * @author: ls
 * @Date: 2020/7/13 17:17
 */
@Slf4j
@Component
public class AuthInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        response.setCharacterEncoding("UTF-8");
//        response.setContentType("application/json; charset=utf-8");
//        response.setHeader("Access-Control-Allow-Origin", "*");
//        response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE, PATCH");
//        response.setHeader("Access-Control-Max-Age", "3600");
//        response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept,Authorization");
        // 1、验证token
        String token = request.getHeader("token");
        if (Strings.isNullOrEmpty(token)) {
            return writeResponseResult(response, ApiResult.failure(ResultCode.USER_NOT_LOGGED_IN));
        }
        // 2、解析token
        Integer tokenUserId = JwtTokenUtil.getValByT(token, SysCode.TOKEN_SECRET_KEY, SysCode.LOGIN_USER, Integer.class);
        if (null == tokenUserId) {
            return writeResponseResult(response, ApiResult.failure(ResultCode.USER_NOT_LOGGED_IN));
        }
        // 3、初始化context设置user
        Integer userId = UserContext.getUserId();
        if (null == userId) {
            UserContext.setUserId(tokenUserId);
        }
        // 4、token如果将过期则续期
        checkTokenExp(response, tokenUserId, token);
        return true;
    }

    /**
     * @Description: 返回结果
     * @author: ls
     * @Date: 2020/7/21 14:09
     */
    private boolean writeResponseResult(HttpServletResponse response, ApiResult result) throws IOException {
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().write(JSON.toJSONString(result));
        return false;
    }

    /**
     * @Description: 过期时间跟当前时间相差24小时则重新生成新的token放入header中
     * @author: ls
     * @Date: 2020/7/21 14:08
     */
    private void checkTokenExp(HttpServletResponse response, Integer userId, String token) {
        Date expDate = JwtTokenUtil.getExpDate(token, SysCode.TOKEN_SECRET_KEY);
        if (DateUtil.difHour(new Date(), expDate) <= SysCode.TOKEN_REFRESH_HOUR) {
            String newToken = JwtTokenUtil.getExpToken(userId);
            response.setHeader("token", newToken);
        }
    }

    /**
     * @Description: 请求执行完成之后需要将变量清空
     * @author: ls
     * @Date: 2020/7/21 14:09
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        UserContext.clear();
    }
}
